import { Injectable, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Payment } from '../../entities/payment.entity';
import { OrderService } from '../order/order.service';
import { AlipayService } from './alipay.service';
import { WechatPayService } from './wechat.service';
import dayjs from 'dayjs';

@Injectable()
export class PaymentService {
  constructor(
    @InjectRepository(Payment)
    private readonly paymentRepository: Repository<Payment>,
    private readonly orderService: OrderService,
    private readonly alipayService: AlipayService,
    private readonly wechatPayService: WechatPayService,
  ) {}

  /**
   * 创建支付
   */
  async createPayment(
    orderId: number,
    userId: string,
    paymentMethod: 'alipay' | 'wechat',
    paymentType?: 'page' | 'wap' | 'native' | 'jsapi',
  ) {
    // 获取订单信息
    const order = await this.orderService.findOne(orderId, userId);

    // 验证订单状态
    if (order.status !== 'pending') {
      throw new BadRequestException('订单状态不允许支付');
    }

    // 验证订单是否过期
    if (order.expireAt && dayjs().isAfter(dayjs(order.expireAt))) {
      throw new BadRequestException('订单已过期');
    }

    // 使用订单号作为支付流水号
    const paymentNo = order.orderNo;

    // 创建支付记录
    const payment = this.paymentRepository.create({
      orderId: order.id.toString(),
      userId,
      paymentNo,
      paymentMethod,
      amount: order.actualAmount,
      status: 'pending',
    });

    await this.paymentRepository.save(payment);

    // 调用第三方支付
    let payUrl: any;
    let qrCode: string | undefined;

    if (paymentMethod === 'alipay') {
      // 支付宝支付
      if (paymentType === 'wap') {
        payUrl = await this.alipayService.createWapPay({
          outTradeNo: paymentNo,
          totalAmount: order.actualAmount,
          subject: `订单支付-${order.orderNo}`,
          body: `订单ID:${orderId}`,
        });
      } else {
        // 默认PC网站支付
        payUrl = await this.alipayService.createPagePay({
          outTradeNo: paymentNo,
          totalAmount: order.actualAmount,
          subject: `订单支付-${order.orderNo}`,
          body: `订单ID:${orderId}`,
        });
      }
    } else if (paymentMethod === 'wechat') {
      // 微信支付
      const result = await this.wechatPayService.createNativePay({
        outTradeNo: paymentNo,
        totalAmount: order.actualAmount,
        description: `订单支付-${order.orderNo}`,
      });
      payUrl = result.code_url;
      qrCode = result.code_url; // 二维码链接
    }

    return {
      paymentNo,
      payUrl,
      qrCode,
      amount: order.actualAmount,
      orderNo: order.orderNo,
    };
  }

  /**
   * 处理支付宝回调
   */
  async handleAlipayNotify(notifyData: any): Promise<boolean> {
    // 验证签名
    const isValid = this.alipayService.verifyNotify(notifyData);

    if (!isValid) {
      throw new Error('签名验证失败');
    }

    const paymentNo = notifyData.out_trade_no;
    const tradeNo = notifyData.trade_no;
    const tradeStatus = notifyData.trade_status;

    // 只处理成功的交易
    if (tradeStatus !== 'TRADE_SUCCESS' && tradeStatus !== 'TRADE_FINISHED') {
      return false;
    }

    // 查找支付记录
    const payment = await this.paymentRepository.findOne({
      where: { paymentNo },
    });

    if (!payment) {
      throw new Error('支付记录不存在');
    }

    // 防止重复回调
    if (payment.status === 'success') {
      return true;
    }

    // 更新支付记录
    payment.status = 'success';
    payment.tradeNo = tradeNo;
    payment.paidAt = new Date();
    payment.notifyData = notifyData;
    await this.paymentRepository.save(payment);

    // 更新订单状态
    await this.orderService.updatePaymentStatus(paymentNo, {
      paymentMethod: 'alipay',
      paymentNo: tradeNo,
      paidAt: new Date(),
    });

    return true;
  }

  /**
   * 处理微信支付回调
   */
  async handleWechatNotify(notifyData: any): Promise<boolean> {
    // 验证签名
    const isValid = await this.wechatPayService.verifyNotify(
      notifyData.headers,
      notifyData.body,
    );

    if (!isValid) {
      throw new Error('签名验证失败');
    }

    // 解密数据
    const decrypted = await this.wechatPayService.decryptNotify(
      notifyData.resource.ciphertext,
      notifyData.resource.nonce,
      notifyData.resource.associated_data,
    );

    const paymentNo = decrypted.out_trade_no;
    const tradeNo = decrypted.transaction_id;
    const tradeStatus = decrypted.trade_state;

    // 只处理成功的交易
    if (tradeStatus !== 'SUCCESS') {
      return false;
    }

    // 查找支付记录
    const payment = await this.paymentRepository.findOne({
      where: { paymentNo },
    });

    if (!payment) {
      throw new Error('支付记录不存在');
    }

    // 防止重复回调
    if (payment.status === 'success') {
      return true;
    }

    // 更新支付记录
    payment.status = 'success';
    payment.tradeNo = tradeNo;
    payment.paidAt = new Date();
    payment.notifyData = notifyData;
    await this.paymentRepository.save(payment);

    // 更新订单状态
    await this.orderService.updatePaymentStatus(paymentNo, {
      paymentMethod: 'wechat',
      paymentNo: tradeNo,
      paidAt: new Date(),
    });

    return true;
  }

  /**
   * 查询支付状态
   */
  async queryPaymentStatus(paymentNo: string) {
    const payment = await this.paymentRepository.findOne({
      where: { paymentNo },
    });

    if (!payment) {
      throw new Error('支付记录不存在');
    }

    return payment;
  }

  /**
   * 退款
   */
  async refund(
    orderId: number,
    refundAmount: number,
    refundReason: string,
  ): Promise<any> {
    // 获取订单信息
    const order = await this.orderService.findOne(orderId);

    // 查找支付记录
    const payment = await this.paymentRepository.findOne({
      where: { orderId: orderId.toString(), status: 'success' },
    });

    if (!payment) {
      throw new BadRequestException('未找到成功的支付记录');
    }

    // 验证退款金额
    if (refundAmount > order.actualAmount) {
      throw new BadRequestException('退款金额不能超过实付金额');
    }

    // 生成退款单号
    const outRefundNo = `REFUND${dayjs().format('YYYYMMDDHHmmss')}${Math.random().toString(36).substring(2, 8).toUpperCase()}`;

    // 调用第三方退款接口
    if (payment.paymentMethod === 'alipay') {
      await this.alipayService.refund({
        outTradeNo: payment.paymentNo,
        refundAmount,
        refundReason,
      });
    } else if (payment.paymentMethod === 'wechat') {
      await this.wechatPayService.refund({
        outTradeNo: payment.paymentNo,
        outRefundNo,
        refundAmount,
        totalAmount: order.actualAmount,
        reason: refundReason,
      });
    }

    // 更新支付记录
    payment.status = 'refunded';
    payment.refundAmount = refundAmount;
    payment.refundReason = refundReason;
    payment.refundedAt = new Date();
    await this.paymentRepository.save(payment);

    // 更新订单状态
    await this.orderService.refund(orderId, refundReason, refundAmount);

    return {
      refundNo: outRefundNo,
      refundAmount,
      refundStatus: 'success',
    };
  }
}
